package com.rankeiot.core.anno.aspect;

import com.rankeiot.core.Current;
import com.rankeiot.core.anno.OperationLog;
import com.rankeiot.core.data.UserInfo;
import com.rankeiot.core.event.LogEvent;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContext;

@Aspect
@RequiredArgsConstructor
public class OperationLogAspect {
    final ApplicationContext context;

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, OperationLog controllerLog, Object result) {
        handleLog(joinPoint, controllerLog, null, result);
    }

    /**
     * 拦截异常操作
     *
     * @param joinPoint 切点
     * @param e         异常
     */
    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, OperationLog controllerLog, Exception e) {
        handleLog(joinPoint, controllerLog, e, null);
    }

    protected void handleLog(final JoinPoint joinPoint, OperationLog controllerLog, final Exception e, Object result) {
        LogEvent logEvent = new LogEvent();
        logEvent.setLog(controllerLog);
        logEvent.setError(e);
        logEvent.setResult(result);
        if (controllerLog.needLogin()) {
            UserInfo user = Current.user();
            logEvent.setUserInfo(user);
        }
        context.publishEvent(logEvent);
    }
}
